home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / comm / tcp / Amster.lha / Amster_Install / Source / napster.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-01  |  14.7 KB  |  765 lines

  1. /*
  2. ** Napster Protocol
  3. */
  4.  
  5. #include "include/config.h"
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/socket.h>
  13. #include <netdb.h>
  14. #include <sys/time.h>
  15. #include <sys/socket.h>
  16. #include <sys/ioctl.h>
  17. #include <netinet/tcp.h>
  18. #include <bsdsocket/socketbasetags.h>
  19. #include <error.h>
  20.  
  21. #include "include/gui.h"
  22. #include "include/channellist.h"
  23. #include "include/hotlist.h"
  24. #include "include/msg.h"
  25. #include "include/napster.h"
  26. #include "include/navigator.h"
  27. #include "include/protos.h"
  28. #include "include/prefs.h"
  29. #include "include/share.h"
  30. #include "include/transfer.h"
  31. #include "include/download.h"
  32. #include "include/upload.h"
  33. #include "amster_Cat.h"
  34.  
  35. #define NAP_SWAPIP(x) ( ((x&0xFF)<<24) | ((x&0xFF00)<<8) | ((x&0xFF0000)>>8) | (x>>24) )
  36.  
  37. struct Library *SocketBase=NULL;
  38. u_long nap_sigmask;
  39. long nap_sock= -1;
  40. long loc_sock= -1;
  41.  
  42. char nap_host[512];
  43. char nap_server[512+6];
  44.  
  45. int nap_state= -1;
  46. #define NAPS_OFF -1
  47. #define NAPS_MAINCON 0
  48. #define NAPS_MAINON 1
  49. #define NAPS_CON 2
  50. #define NAPS_ON 3
  51.  
  52. char nap_buffer[AMSTER_NAPBUFSIZE];
  53. char *nap_buf = &nap_buffer[4];
  54.  
  55. char *nap_linktype[] = {
  56.     (char*)_MSG_LINE_UNKNOWN,
  57.     (char*)_MSG_LINE_14400,
  58.     (char*)_MSG_LINE_28800,
  59.     (char*)_MSG_LINE_33600,
  60.     (char*)_MSG_LINE_57600,
  61.     (char*)_MSG_LINE_64000,
  62.     (char*)_MSG_LINE_128000,
  63.     (char*)_MSG_LINE_CABLE,
  64.     (char*)_MSG_LINE_DSL,
  65.     (char*)_MSG_LINE_T1,
  66.     (char*)_MSG_LINE_T3,
  67.     NULL
  68. };
  69.  
  70. BOOL nap_logininit(void);
  71. int nap_connect(char *server);
  72. int nap_recv(u_char *buf);
  73. void nap_interpret(u_int com, char *data);
  74. void nap_parseresult(int type, char *data);
  75. char *nap_token(char **s);
  76. u_long nap_ltoken(char **str);
  77. int nap_itoken(char **str);
  78. int createlistener(void);
  79. char *getneterror(int type);
  80.  
  81.  
  82. void nap_login_fromlist(char *server)
  83. {
  84.     if (!nap_logininit()) return;
  85.  
  86.     nap_state = NAPS_CON;
  87.     gui_stat((char*)MSG_STATUS2_CONNECTINGTO, server);
  88.     if (!nap_connect(server)) {
  89.         nap_logout();
  90.         return;
  91.     }
  92. }
  93.  
  94.  
  95. void nap_login(void)
  96. {
  97.     if (!nap_logininit()) return;
  98.  
  99.     if (prf->server) {
  100.         nap_state = NAPS_CON;
  101.         gui_stat((char*)MSG_STATUS2_CONNECTINGTO, prf->server);
  102.         if (!nap_connect(prf->server)) {
  103.             nap_logout();
  104.             return;
  105.         }
  106.     }
  107.     else {
  108.         nap_state = NAPS_MAINCON;
  109.         gui_stat((char*)MSG_STATUS2_FINDINGOPTIMAL);
  110.         if (!nap_connect(prf->mainserver)) {
  111.             nap_logout();
  112.             return;
  113.         }
  114.     }
  115. }
  116.  
  117.  
  118. BOOL nap_logininit(void)
  119. {
  120.     gui_state(CONNECTING);
  121.     SocketBase = OpenLibrary("bsdsocket.library", 0);
  122.     if (!SocketBase) {
  123.         gui_stat((char *)MSG_NO_TCPIP);
  124.         nap_logout();
  125.         return FALSE;
  126.     }
  127.     SocketBaseTags(SBTM_SETVAL(SBTC_SIGIOMASK), (char *)nap_sigmask, TAG_DONE);
  128.  
  129.     return TRUE;
  130. }
  131.  
  132.  
  133. void nap_logout(void)
  134. {
  135.     nap_state = NAPS_OFF;
  136.     if (nap_sock>=0) CloseSocket(nap_sock);
  137.     nap_sock = -1;
  138.     if (loc_sock>=0) CloseSocket(loc_sock);
  139.     loc_sock = -1;
  140.     if (SocketBase) CloseLibrary(SocketBase);
  141.     SocketBase = NULL;
  142.     gui_state(DISCONNECTED);
  143. }
  144.  
  145.  
  146. void nap_listen(void)
  147. {
  148.     static u_char buf[AMSTER_NAPBUFSIZE];
  149.     static struct fd_set fds;
  150.     static struct timeval tv;
  151.  
  152.     if (nap_state == NAPS_OFF) return;
  153.  
  154.     FD_ZERO(&fds);
  155.     FD_SET(nap_sock,&fds);
  156.     tv.tv_sec = 0;
  157.     tv.tv_usec = 0;
  158.  
  159.     switch (nap_state) {
  160.         case NAPS_MAINCON:
  161.             if (WaitSelect(nap_sock+1,NULL,&fds,NULL,&tv,0) != 1) break;
  162.             {
  163.                 long tmp=0;
  164.                 IoctlSocket(nap_sock,FIONBIO,(char*)&tmp);
  165.                 nap_state = NAPS_MAINON;
  166.             }
  167.  
  168.         case NAPS_MAINON:
  169.             if (WaitSelect(nap_sock+1,&fds,NULL,NULL,&tv,0) != 1) break;
  170.             {
  171.                 int r;
  172.                 char *col;
  173.                 r = recv(nap_sock, buf, 255,0);
  174.                 CloseSocket(nap_sock);
  175.                 nap_sock = -1;
  176.                 if (r <= 0) {
  177.                     gui_stat((char *)MSG_STATUS2_CONNECTFAILED_TMP, nap_server, getneterror(Errno()));
  178.                     nap_logout();
  179.                     return;
  180.                 }
  181.                 buf[r] = 0;
  182.                 col = strchr(buf, '\n');
  183.                 if (col) *col=0;
  184.                 if (strncmp(buf,"wait",4)==0 || strncmp(buf,"busy",4)==0 || strncmp(buf,"127.0.0.1",9)==0) {
  185.                     /* Sometimes the server returns "127.0.0.1:1111" - quite odd. */
  186.                     gui_stat((char *)MSG_INFO_SERVERBUSY);
  187.                     nap_logout();
  188.                     return;
  189.                 }
  190.                 gui_debugf((char *)MSG_INFO_OPTIMAL, buf);
  191.                 gui_stat((char *)MSG_STATUS2_CONNECTINGTO, buf);
  192.                 if (!nap_connect(buf)) {
  193.                     nap_logout();
  194.                     return;
  195.                 }
  196.                 nap_state = NAPS_CON;
  197.             }
  198.             break;
  199.  
  200.         case NAPS_CON:
  201.             if (WaitSelect(nap_sock+1,NULL,&fds,NULL,&tv,0) != 1) break;
  202.             {
  203.                 long tmp=0;
  204.                 int r = 0;
  205.  
  206.                 IoctlSocket(nap_sock, FIONBIO, (char *)&tmp);
  207.  
  208.                 nap_state = NAPS_ON;
  209.                 gui_stat((char *)MSG_STATUS2_LOGGINGINTO, nap_server);
  210.                 gui_state(LOGGING_IN);
  211.  
  212.                 DoMethod(gui->WI_Navigator, NAVI_MARKSERVER, nap_server);
  213.  
  214.                 if (prf->regflag > 0) {
  215. /*                    r = nap_sendbuf(NAPC_CHECK_NAME, prf->user);*/
  216.  
  217.                     if (prf->regflag == 1) {
  218.                         sprintf(nap_buf, "%s %s %d \"%s\" %d %s", prf->user, prf->pass, 0/*prf->port*/, prf->napvers, prf->link, prf->email);
  219.                     }
  220.                     else {
  221.                         sprintf(nap_buf, "%s %s %d \"%s\" %d %s", gui->ConnectUser, gui->ConnectPw, 0/*prf->port*/, prf->napvers, prf->link, prf->email);
  222.                     }
  223.                     nap_send(NAPC_NEW_USER);
  224.  
  225.                     /* Create user before we attempt to log in */
  226.  
  227.                     if (r == -1) {
  228.                         prf->regflag = 1;
  229.                         if (Errno() == EPIPE) {
  230.                             gui_stat((char *)MSG_STATUS2_CONNECTFAILED_TMP, nap_server, getneterror(Errno()));
  231.                             nap_logout();
  232.                             return;
  233.                         }
  234.                     }
  235.                 }
  236.  
  237.                 if (prf->regflag == 1) {
  238.                     sprintf(nap_buf, "%s %s %d \"%s\" %d", prf->user, prf->pass, 0/*prf->port*/, prf->napvers, prf->link);
  239.                 }
  240.                 else {
  241.                     sprintf(nap_buf, "%s %s %d \"%s\" %d", gui->ConnectUser, gui->ConnectPw, 0/*prf->port*/, prf->napvers, prf->link);
  242.                 }
  243.                 prf->regflag = 1;
  244.                 nap_send(NAPC_LOGIN_REQUEST);
  245.             }
  246.             break;
  247.  
  248.         case NAPS_ON:
  249.             while (1) {
  250.                 int r;
  251.                 FD_ZERO(&fds);
  252.                 FD_SET(nap_sock,&fds);
  253.                 tv.tv_sec=0;
  254.                 tv.tv_usec=0;
  255.                 if (WaitSelect(nap_sock+1, &fds, NULL, NULL, &tv, 0) < 1) {
  256.                     return;
  257.                 }
  258.  
  259.                 r = nap_recv(buf);
  260.                 if (r == -1) {
  261.                     gui_stat((char *)MSG_ERR_NETWORKERROR);
  262.                     nap_logout();
  263.                     return;
  264.                 }
  265.                 if (r == 1) nap_interpret(buf[2]+(buf[3]<<8), buf+4);
  266.             }
  267.     }
  268. }
  269.  
  270.  
  271. void nap_send(u_int com)
  272. {
  273.     int len;
  274.  
  275.     if (gui_onlinestate < CONNECTING) return;
  276.     /* Avoid crash - but calling functions should check this first! */
  277.  
  278.     len = strlen(nap_buf);
  279.     nap_buffer[0] = len&0xFF;
  280.     nap_buffer[1] = (len&0xFF00)>>8;
  281.     nap_buffer[2] = com&0xFF;
  282.     nap_buffer[3] = (com&0xFF00)>>8;
  283.     send(nap_sock,nap_buffer,4+len,0);
  284. }
  285.  
  286.  
  287. int nap_sendbuf(u_int com, char *buf)
  288. {
  289.     static u_char hdr[4];
  290.     int len, r;
  291.  
  292.     if (gui_onlinestate < CONNECTING) return -1;
  293.     /* Avoid crash - but calling functions should check this first! */
  294.  
  295.     len = strlen(buf);
  296.     hdr[0] = len&0xFF;
  297.     hdr[1] = (len&0xFF00)>>8;
  298.     hdr[2] = com&0xFF;
  299.     hdr[3] = (com&0xFF00)>>8;
  300.  
  301.     r = send(nap_sock, hdr, 4, 0);
  302.     if (r <= 0) return r;
  303.  
  304.     r = send(nap_sock, buf, len, 0);
  305.     if (r <= 0) return r;
  306.     else return 0;
  307. }
  308.  
  309.  
  310. void nap_songfree(song s)
  311. {
  312.     if (!s) return;
  313.     if (s->title) free(s->title);
  314.     if (s->md5) free(s->md5);
  315.     if (s->user) free(s->user);
  316.     free(s);
  317. }
  318.  
  319.  
  320. song nap_songdup(song s)
  321. {
  322.     song sn;
  323.  
  324.     sn = malloc(sizeof(_song));
  325.     if (!sn) return(NULL);
  326.     memset(sn,0,sizeof(_song));
  327.  
  328.     sn->title = strdup(s->title);
  329.     sn->md5 = strdup(s->md5);
  330.     sn->size = s->size;
  331.     sn->bit = s->bit;
  332.     sn->freq = s->freq;
  333.     sn->time = s->time;
  334.     sn->user = strdup(s->user);
  335.     sn->ip = s->ip;
  336.     sn->link = s->link;
  337.  
  338.     if (!sn->title || !sn->md5 || !sn->user) {
  339.         nap_songfree(sn);
  340.         return(NULL);
  341.     }
  342.  
  343.     return(sn);
  344. }
  345.  
  346.  
  347. char *nap_strippath(char *name)
  348. {
  349.     int i;
  350.     char tmp;
  351.  
  352.     for (i=strlen(name)-1; i>=0; i--) {
  353.         tmp = name[i];
  354.         if (tmp==':' || tmp=='/' || tmp=='\\') return(name+i+1);
  355.     }
  356.     return(name);
  357. }
  358.  
  359.  
  360. /* private functions */
  361.  
  362. int nap_connect(char *server)
  363. {
  364.     struct hostent *host;
  365.     struct sockaddr_in sin;
  366.     long tmp=1;
  367.     char *addr, *col;
  368.     int port = 0;
  369.  
  370.     addr = strdup(server);
  371.     col = strtok(addr, ":");
  372.     if (col) col = strtok(NULL,"");
  373.     if (col) port = atoi(col);
  374.  
  375.     if (!port) {
  376.         gui_stat((char *)MSG_INFO_PORTNEEDED);
  377.         free(addr);
  378.         return(0);
  379.     }
  380.  
  381.     host = gethostbyname(addr);
  382.     free(addr);
  383.     if (!host) {
  384.         gui_stat((char *)MSG_ERR_LOOKUPFAILED);
  385.         return(0);
  386.     }
  387.     memcpy(&sin.sin_addr, host->h_addr, host->h_length);
  388.     sin.sin_family = host->h_addrtype;
  389.     sin.sin_port = port;
  390.     sin.sin_len = sizeof(sin);
  391.  
  392.     strcpy(nap_host, host->h_name);
  393.     strcpy(nap_server, server);
  394.  
  395.     nap_sock = socket(AF_INET,SOCK_STREAM,0);
  396.     if (nap_sock<0) {
  397.         gui_debug((char *)MSG_ERR_SOCKETERROR);
  398.         return(0);
  399.     }
  400.  
  401.     IoctlSocket(nap_sock,FIOASYNC,(char *)&tmp);
  402.     IoctlSocket(nap_sock,FIONBIO,(char *)&tmp);
  403.  
  404.     tmp = connect(nap_sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in));
  405.     if(tmp != -1) return(1);
  406.     if(Errno()==EINPROGRESS) return(1);
  407.  
  408.     gui_stat((char *)MSG_STATUS2_CONNECTFAILED_TMP, nap_host, getneterror(Errno()));
  409.     return(0);
  410. }
  411.  
  412.  
  413. int nap_recv(u_char *buf)
  414. {
  415.     static u_int blen=0;
  416.     u_int len=4;
  417.     int ret;
  418.  
  419.     if (blen>=4) {
  420.         len = buf[0] + (buf[1]<<8) + 4;
  421.         if (len==0) {
  422.             buf[blen] = 0;
  423.             blen = 0;
  424.             return(1);
  425.         }
  426.     }
  427.  
  428.  
  429.     ret = recv(nap_sock, buf+blen, len-blen, 0);
  430.     if (ret <= 0) {
  431.         blen = 0;
  432.         return(-1);
  433.     }
  434.     blen += ret;
  435.  
  436.  
  437.     if (blen == 4) {
  438.         len = buf[0] + (buf[1]<<8) + 4;
  439.         if (len == 0) {
  440.             buf[blen] = 0;
  441.             blen = 0;
  442.             return(1);
  443.         }
  444.     }
  445.  
  446.     if (blen == len) {
  447.         buf[blen] = 0;
  448.         blen = 0;
  449.         return(1);
  450.     }
  451.  
  452.     return(0);
  453. }
  454.  
  455.  
  456. void nap_interpret(u_int com, char *data)
  457. {
  458.     switch(com) {
  459.         case NAPC_PUBLICMSGRECV:
  460.         case NAPC_JOINACK:
  461.         case NAPC_JOINMSG:
  462.         case NAPC_USERPART:
  463.         case NAPC_USERLIST:
  464.         case NAPC_USERLISTEND:
  465.         case NAPC_CHANNELTOPIC:
  466.             chat_interpret(com, data);
  467.             break;
  468.         case NAPC_CHANNELPART:
  469.             gui_debugf("Left channel %s.", data);
  470.             break;
  471.         case NAPC_CHANNEL_ENTRY:
  472.             {
  473.             char *channel;
  474.             int users;
  475.  
  476.             channel = nap_token(&data);
  477.             users = nap_itoken(&data);
  478.             DoMethod(gui->WI_ChannelList, CHANLIST_ENTRY, channel, users, data);
  479.             break;
  480.             }
  481.         case NAPC_LIST_CHANNELS:
  482.             /* End of channel list */
  483.             break;
  484.         case NAPC_USER_SIGNON:
  485.         case NAPC_USER_SIGNOFF:
  486.         case NAPC_HOTLIST_ACK:
  487.         case NAPC_HOTLIST_ERROR:
  488.             HotlistInterpret(com, data);
  489.             break;
  490.         case NAPC_LOGINERROR:
  491.             gui_debugf((char *)MSG_INFO_LOGINERROR, data);
  492.             break;
  493.         case NAPC_REGSUCCESS:
  494.             gui_debug((char *)MSG_INFO_REGSUCCESS);
  495.             break;
  496.         case NAPC_REGUSED:
  497.             gui_debug((char *)MSG_INFO_REGUSED);
  498.             break;
  499.         case NAPC_SEARCHRESULT:
  500.             nap_parseresult(0, data);
  501.             break;
  502.         case NAPC_SEARCHCOMPLETE:
  503.             gui_found(NULL, 0);
  504.             break;
  505.         case NAPC_BROWSERESULT:
  506.             nap_parseresult(1, data);
  507.             break;
  508.         case NAPC_BROWSECOMPLETE:
  509.             gui_found(NULL, 1);
  510.             break;
  511.         case NAPC_FILECOUNT:
  512.             {
  513.             int a,b,c;
  514.             a = nap_itoken(&data);
  515.             b = nap_itoken(&data);
  516.             c = nap_itoken(&data);
  517.             gui_srvstat(a,b,c);
  518.             break;
  519.             }
  520.         case NAPC_PRIVATEMSG:
  521.             {
  522.             char *nick;
  523.  
  524.             nick = nap_token(&data);
  525.             DoMethod(gui->mwin, MSG_GOT, nick, data);
  526.             break;
  527.             }
  528.         case NAPC_FILEINFO:
  529.             {
  530.             char *title,*user;
  531.             u_long ip;
  532.             int port;
  533.  
  534.             user = nap_token(&data);
  535.             ip = nap_ltoken(&data);
  536.             port = nap_itoken(&data);
  537.             title = nap_token(&data);
  538.  
  539.             DoMethod(gui->dwin, DL_START, title, user, NAP_SWAPIP(ip), port);
  540.             }
  541.             break;
  542.         case NAPC_LOGINRESP:
  543.             DoMethod(gui->WI_Hotlist, HOTLIST_UPLOAD);
  544.             DoMethod(gui->shwin, SHARE_NOTIFYALL);
  545.             gui_state(ONLINE);
  546.             break;
  547.         case NAPC_WHOISRESP:
  548.             msg_gotwhois(data);
  549.             break;
  550.         case NAPC_WHOWASRESP:
  551.             {
  552.             char *user, *level;
  553.             u_long lastseen;
  554.  
  555.             user = nap_token(&data);
  556.             level = nap_token(&data);
  557.             lastseen = nap_ltoken(&data);
  558.  
  559.             DoMethod(gui->mwin, MSG_WHOWAS, user, level, lastseen);
  560.             }
  561.             break;
  562.         case NAPC_UPLOADREQ:
  563.             {
  564.             char *user,*fname;
  565.             user = nap_token(&data);
  566.             fname = nap_token(&data);
  567.             upload_req(user,fname);
  568.             }
  569.             break;
  570.         case NAPC_ALTDLACK:
  571.             {
  572.             char *nick, *fname, *md5;
  573.             u_long ip;
  574.             int port, speed;
  575.  
  576.             nick = nap_token(&data);
  577.             ip = nap_ltoken(&data);
  578.             port = nap_itoken(&data);
  579.             fname = nap_token(&data);
  580.             md5 = nap_token(&data);
  581.             speed = nap_itoken(&data);
  582.  
  583.             ul_startq(fname, nick, NAP_SWAPIP(ip), port, speed);
  584.             }
  585.             break;
  586.         case NAPC_REMOTEQUEUEFULL:
  587.             {
  588.             char *nick, *fname;
  589.             int size, limit;
  590.             nick = nap_token(&data);
  591.             fname = nap_token(&data);
  592.             size = nap_itoken(&data);
  593.             limit = nap_itoken(&data);
  594.  
  595.             DoMethod(gui->dwin, DL_RETRY, fname, nick, limit);
  596.             }
  597.             break;
  598.         case NAPC_GETERROR:
  599.         case NAPC_GETERROR2:
  600.             {
  601.             char *user, *fname;
  602.             user = nap_token(&data);
  603.             fname = nap_token(&data);
  604.             DoMethod(gui->dwin, DL_SETERROR, fname, user, ERROR_LOGGEDOUT);
  605.             }
  606.             break;
  607.         case NAPC_GENERALERROR:
  608.             gui_debugf((char *)MSG_INFO_ERROR, data);
  609.             break;
  610.         case NAPC_SYSMSG:
  611.             gui_debug(data);
  612.             break;
  613.         case NAPC_GLOBALMSG:
  614.             {
  615.             char *nick, buf[50];
  616.  
  617.             nick = nap_token(&data);
  618.             sprintf(buf, MSG_GLOBALMESSAGE_TITLE, nick);
  619.  
  620.             MUI_Request(gui->app, gui->win, 0L,
  621.                 buf,
  622.                 (char *)MSG_OK_GAD,
  623.                 data);
  624.             }
  625.             break;
  626.         default:
  627.             gui_debugf("<<%d:%s>>",com,data);
  628.     }
  629. }
  630.  
  631.  
  632. void nap_parseresult(int type, char *data)
  633. {
  634.     song s;
  635.     char *tmp=data;
  636.  
  637.     s = malloc(sizeof(_song));
  638.     if(!s) return;
  639.     memset(s,0,sizeof(_song));
  640.  
  641.     switch (type) {
  642.         case 0:    /* Search result */
  643.             s->title = strdup(nap_token(&tmp));
  644.             s->md5 = strdup(nap_token(&tmp));
  645.             strtok(s->md5,"-");
  646.             s->size = nap_ltoken(&tmp);
  647.             s->bit = nap_itoken(&tmp);
  648.             s->freq = nap_itoken(&tmp);
  649.             s->time = nap_itoken(&tmp);
  650.             s->user = strdup(nap_token(&tmp));
  651.             s->ip = nap_ltoken(&tmp);
  652.             s->ip = NAP_SWAPIP(s->ip);
  653.             s->link = nap_itoken(&tmp);
  654.             break;
  655.  
  656.         case 1: /* Browse result */
  657.             s->user = strdup(nap_token(&tmp));
  658.             s->title = strdup(nap_token(&tmp));
  659.             s->md5 = strdup(nap_token(&tmp));
  660.             strtok(s->md5, "-");
  661.             s->size = nap_ltoken(&tmp);
  662.             s->bit = nap_itoken(&tmp);
  663.             s->freq = nap_itoken(&tmp);
  664.             s->time = nap_itoken(&tmp);
  665.             break;
  666.     }
  667.  
  668.     if (!s->user || !s->title || !s->md5) {
  669.         nap_songfree(s);
  670.         return;
  671.     }
  672.  
  673.     gui_found(s, type);
  674. }
  675.  
  676.  
  677. u_long nap_ltoken(char **str)
  678. {
  679.     char *t;
  680.  
  681.     t = nap_token(str);
  682.     if(!t) return(0);
  683.     return((u_long)atol(t));
  684. }
  685.  
  686.  
  687. int nap_itoken(char **str)
  688. {
  689.     char *t;
  690.  
  691.     t = nap_token(str);
  692.     if(!t) return(0);
  693.     return(atoi(t));
  694. }
  695.  
  696.  
  697. char *nap_token(char **str)
  698. {
  699.     int sf=0,i,len=0;
  700.     char c, *t=NULL;
  701.  
  702.     if (!*str) return(NULL);
  703.  
  704.     for (i=0; ; i++) {
  705.         c = *(*str + i);
  706.         switch (c) {
  707.             case '\0':
  708.                 *str = NULL;
  709.                 if (len==0 || sf) return(NULL);
  710.                 return(t);
  711.             case '"':
  712.                 if (sf) {
  713.                     *(*str+i) = 0;
  714.                     *str = *str+i+1;
  715.                     return(t);
  716.                 }
  717.                 sf=1;
  718.                 break;
  719.             case ' ':
  720.                 if (len==0) break;
  721.                 if (!sf) {
  722.                     *(*str+i) = 0;
  723.                     *str = *str+i+1;
  724.                     return(t);
  725.                 }
  726.                 break;
  727.             default:
  728.                 if (!t) t=*str+i;
  729.                 len++;
  730.         }
  731.     }
  732. }
  733.  
  734.  
  735. char *getneterror(int type)
  736. {
  737.     char *message, buf[512];
  738.  
  739.     switch (type) {
  740.         case ENETDOWN:
  741.             message = (char *)MSG_NETERROR_ENETDOWN;
  742.             break;
  743.         case ENETUNREACH:
  744.             message = (char *)MSG_NETERROR_ENETUNREACH;
  745.             break;
  746.         case ECONNRESET:
  747.             message = (char *)MSG_NETERROR_ECONNRESET;
  748.             break;
  749.         case ETIMEDOUT:
  750.             message = (char *)MSG_NETERROR_ETIMEDOUT;
  751.             break;
  752.         case ECONNREFUSED:
  753.             message = (char *)MSG_NETERROR_ECONNREFUSED;
  754.             break;
  755.         case EPIPE:
  756.             message = (char *)MSG_NETERROR_EPIPE;
  757.             break;
  758.         default:
  759.             sprintf(buf, MSG_NETERROR_UNKNOWN, type);
  760.             message = buf;
  761.     }
  762.  
  763.     return message;
  764. }
  765.